<template>
  <span @click="approval"
    ><slot></slot>
    <LoadingBox v-if="showLoading" />
    <ProcessLayout class="wrap" v-if="showVisible" @click.stop="">
      <template #title> {{ t('审批流程') }}【{{ data.item.name }}】 </template>
      <template #close>
        <a-button type="primary" class="clean-icon" @click.stop="close">{{ t('关闭') }}</a-button>
      </template>
      <template #left>
        <FlowPanel
          :xml="data.xml"
          :taskRecords="data.taskRecords"
          :predecessorTasks="selectedPredecessorTasks"
          :processId="props.processId"
          position="top"
        >
          <FormInformation
            :opinionsComponents="data.opinionsComponents"
            :opinions="data.opinions"
            :disabled="false"
            :formInfos="data.formInfos"
            :formAssignmentData="data.formAssignmentData"
            ref="formInformation"
            @get-form-configs="(config) => (formConfigs = config)"
          />
        </FlowPanel>
      </template>
      <template #right>
        <a-tabs>
          <a-tab-pane key="1" :tab="t('审批信息')">
            <NodeHead :nodeName="t('基础信息')" />

            <div class="description-box">
              <ProcessInfo class="item-box" :item="data.item">
                <NodeHead :nodeName="t('审批信息')" />
                <div
                  class="text-box"
                  v-if="approvalData.buttonConfigs && approvalData.buttonConfigs.length > 0"
                >
                  <div class="text-label">{{ t('审批结果：') }}</div>
                  <span class="flex-1">
                    <a-radio-group
                      class="approve-group"
                      v-model:value="approvedType"
                      name="approvedType"
                      @change="changeApprovedType"
                    >
                      <span v-for="(item, index) in approvalData.buttonConfigs" :key="index">
                        <a-radio
                          v-if="item.approveType !== ApproveType.OTHER"
                          :value="item.approveType"
                        >
                          {{ item.buttonName }}
                        </a-radio>
                      </span>
                    </a-radio-group>
                    <a-radio-group
                      class="approve-group"
                      v-model:value="approvedType"
                      name="buttonCode"
                    >
                      <span v-for="(item, index) in approvalData.buttonConfigs" :key="index">
                        <a-radio
                          v-if="item.approveType === ApproveType.OTHER"
                          :value="item.buttonCode"
                          @change="changeButtonCodeType"
                        >
                          {{ item.buttonName }}
                        </a-radio>
                      </span>
                    </a-radio-group>
                  </span>
                </div>
                <div class="text-box" v-if="approvalData.approvedType === ApproveType.REJECT">
                  <div class="text-label">{{ t('驳回节点：') }}</div>
                  <a-select class="w-full flex-1" v-model:value="approvalData.rejectNodeActivityId">
                    <a-select-option
                      v-for="(item, index) in approvalData.rejectNodeActivityIds"
                      :key="index"
                      :value="item.activityId"
                      >{{ item.activityName }}</a-select-option
                    >
                  </a-select>
                </div>
                <div class="text-box">
                  <div class="text-label">{{ t('审批内容：') }}</div>
                  <a-textarea
                    class="flex-1"
                    v-model:value="approvalData.approvedContent"
                    :rows="6"
                    :maxlength="100"
                  />
                </div>
              </ProcessInfo>
            </div>
            <a-form
              class="approval-form"
              :model="approvalData.stampInfo"
              :label-col="{ span: 6 }"
              :wrapper-col="{ span: 18 }"
              @finish="onFinish"
              @finish-failed="onFinishFailed"
            >
              <!-- 电子签章 -->
              <a-form-item
                :label="t('电子签章')"
                name="stampId"
                :rules="[{ required: true, message: t('请选择电子签章') }]"
                v-if="data.hasStamp"
              >
                <SelectStamp
                  v-if="data.hasStamp"
                  v-model:stampId="approvalData.stampInfo.stampId"
                />
              </a-form-item>
              <a-form-item
                :label="t('签章密码')"
                name="password"
                :rules="[{ required: true, message: t('请输入签章密码') }]"
                v-if="data.hasStampPassword"
              >
                <a-input-password v-model:value="approvalData.stampInfo.password" />
              </a-form-item>

              <ApproveUser
                v-if="approveUserData.visible"
                :taskList="approveUserData.list"
                :schemaId="approveUserData.schemaId"
                @change="changeApproveUserData"
              />
              <div class="button-box">
                <a-button
                  type="primary"
                  html-type="submit"
                  class="mr-2"
                  :loading="data.submitLoading"
                  >{{ t('审批') }}</a-button
                >
                <!-- 转办 -->
                <TransferUser :taskId="props.taskId" @close="close" />
                <!-- 加签减签 -->
                <AddOrSubtract
                  v-if="approvalData.isAddOrSubSign"
                  :schemaId="props.schemaId"
                  :taskId="props.taskId"
                />
              </div>
            </a-form>
          </a-tab-pane>
          <a-tab-pane key="2" :tab="t('传阅信息')" force-render>
            <MemberTable v-model:memberList="approvalData.circulateConfigs" :isCommonType="true" />
          </a-tab-pane>
          <a-tab-pane key="3" :tab="t('打印表单')" force-render>
            <NodeHead :nodeName="t('打印属性')" />
            <a-form
              :model="printData"
              :label-col="{ span: 8 }"
              :wrapper-col="{ span: 16 }"
              @finish="printForm"
            >
              <a-form-item :label="t('边框颜色')" name="borderColor">
                <ColorPicker v-model:value="printData.borderColor" />
              </a-form-item>
              <a-form-item :label="t('页面风格')" name="style">
                <a-select v-model:value="printData.style" style="width: 100%">
                  <a-select-option value="1">默认风格</a-select-option>
                  <a-select-option value="2">公文风格</a-select-option>
                  <a-select-option value="3">发文稿纸风格</a-select-option>
                  <a-select-option value="4">下划线风格</a-select-option>
                </a-select>
              </a-form-item>
              <a-form-item label="标题下划线" name="underline">
                <a-select v-model:value="printData.underline" style="width: 100%">
                  <a-select-option value="1">是，标题带有下划线</a-select-option>
                  <a-select-option value="0">否，标题不带下划线</a-select-option>
                </a-select>
              </a-form-item>
              <div class="button-box">
                <a-button
                  type="primary"
                  html-type="submit"
                  class="mr-2"
                  :loading="printData.submitLoading"
                  >{{ t('打印当前页表单') }}</a-button
                >
              </div>
            </a-form>
          </a-tab-pane>
        </a-tabs>
      </template>
    </ProcessLayout>
    <FormPrint
      v-if="isShowPrint"
      v-model:isShowPrint="isShowPrint"
      :formConfigs="formConfigs"
      :printData="printData"
    />
  </span>
</template>

<script setup lang="ts">
  import { computed, reactive, ref, defineAsyncComponent, onMounted, provide, Ref } from 'vue';
  import ProcessLayout from './flow/Layout.vue';
  import FormInformation from './flow/FormInformation.vue';
  import FlowPanel from './flow/FlowPanel.vue';
  import ProcessInfo from './flow/ProcessInfo.vue';
  import FormPrint from './print/FormPrint.vue';
  import { NodeHead } from '/@/components/ModalPanel/index';
  import { getApprovalProcess, getRejectNode, postApproval } from '/@/api/workflow/task';
  import userTaskItem from './../hooks/userTaskItem';
  import { ApproveTask, PostApprovalData, rejectNodeItem } from '/@/model/workflow/bpmnConfig';
  import { LoadingBox } from '/@/components/ModalPanel/index';
  import { ButtonConfigItem } from '/@/model/workflow/workflowConfig';
  import { MemberConfig } from '/@/model/workflow/memberSetting';
  import { ApproveCode, ApproveType } from '/@/enums/workflowEnum';
  import { separator } from '../../design/bpmn/config/info';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { notification } from 'ant-design-vue';
  import { ColorPicker } from '/@/components/ColorPicker';
  const { t } = useI18n();
  const ApproveUser = defineAsyncComponent(() => import('./flow/ApproveUser.vue'));
  const AddOrSubtract = defineAsyncComponent(() => import('./flow/AddOrSubtract.vue'));
  const TransferUser = defineAsyncComponent(() => import('./flow/TransferUser.vue'));
  const MemberTable = defineAsyncComponent(
    () => import('/@bpmn/components/member/MemberTable.vue'),
  );
  const SelectStamp = defineAsyncComponent(() => import('./stamp/SelectStamp.vue'));
  const props = withDefaults(
    defineProps<{
      schemaId: string;
      processId: string;
      taskId: string;
      visible?: boolean;
    }>(),
    {
      schemaId: '',
      processId: '',
      taskId: '',
      visible: false,
    },
  );
  let emits = defineEmits(['close']);

  let formInformation = ref();
  let showVisible = ref(false);
  let showLoading = ref(false);
  let approvedType = ref(ApproveType.AGREE);
  let approvalData: {
    isCountersign: Boolean; //是否会签节点
    isAddOrSubSign: Boolean; //是否加签减签
    stampInfo: {
      stampId: string;
      password: string;
    };
    buttonConfigs: Array<ButtonConfigItem>;
    approvedType: ApproveType;
    approvedContent: string;
    approvedResult: string;
    rejectNodeActivityId: string;
    rejectNodeActivityIds: Array<rejectNodeItem>;
    circulateConfigs: Array<MemberConfig>;
  } = reactive({
    isCountersign: false,
    isAddOrSubSign: false,
    stampInfo: {
      stampId: '',
      password: '',
    },
    buttonConfigs: [],
    approvedType: ApproveType.AGREE,
    approvedResult: ApproveCode.AGREE,
    approvedContent: '',
    rejectNodeActivityId: '',
    rejectNodeActivityIds: [],
    circulateConfigs: [],
  });

  const printData = ref({
    borderColor: '#000000',
    style: '1',
    underline: '0',
    submitLoading: false,
  });
  const formConfigs = ref();
  const tabActiveKey = ref<number>(0);
  const isShowPrint = ref<boolean>(false);
  provide<Ref<number>>('tabActiveKey', tabActiveKey);
  const { data, approveUserData, initProcessData, notificationError, notificationSuccess } =
    userTaskItem();
  const validateSuccess = ref(false);
  onMounted(() => {
    if (props.visible) {
      approval();
    }
  });
  const selectedPredecessorTasks = computed(() => {
    return data.predecessorTasks.filter((ele) => {
      return ele.taskId;
    });
  });

  // 审批
  async function approval() {
    showLoading.value = true;
    reset();
    if (props.taskId) {
      try {
        let res = await getApprovalProcess(props.taskId, props.processId);
        initProcessData(res);
        if (res.buttonConfigs) {
          approvalData.buttonConfigs = res.buttonConfigs;
        }
        if (res.relationTasks) {
          data.predecessorTasks = res.relationTasks;
        }
        if (res.isAddOrSubSign) {
          approvalData.isAddOrSubSign = res.isAddOrSubSign;
        }

        approvalData.approvedType = ApproveType.AGREE;
        approvedType.value = ApproveType.AGREE;
        approvalData.approvedContent = '';
        approvalData.rejectNodeActivityId = '';
        approvalData.rejectNodeActivityIds = [];
        approvalData.circulateConfigs = [];
        showLoading.value = false;
        showVisible.value = true;
      } catch (error) {
        showLoading.value = false;
        emits('close');
      }
    } else {
      // 只能选一个
      showLoading.value = false;
      showVisible.value = false;
      notification.open({
        type: 'error',
        message: t('审批'),
        description: t('请选择一个流程进行审批'),
      });
    }
  }

  async function changeApprovedType() {
    approvalData.approvedType = approvedType.value;
    if (approvedType.value == ApproveType.AGREE) {
      approvalData.approvedResult = ApproveCode.AGREE;
    } else if (approvedType.value == ApproveType.REJECT) {
      approvalData.rejectNodeActivityIds = await getRejectNode(props.processId, props.taskId);
      approvalData.approvedResult = ApproveCode.REJECT;
    } else if (approvedType.value == ApproveType.DISAGREE) {
      approvalData.approvedResult = ApproveCode.DISAGREE;
    } else if (approvedType.value == ApproveType.FINISH) {
      approvalData.approvedResult = ApproveCode.FINISH;
    } else {
      approvalData.approvedResult = '';
    }
  }
  function changeButtonCodeType(v) {
    approvalData.approvedType = ApproveType.OTHER;
    approvalData.approvedResult = v.target.value;
  }
  function getUploadFileFolderIds(formModels) {
    let fileFolderIds: Array<string> = [];
    let uploadComponentIds = formInformation.value.getUploadComponentIds();
    uploadComponentIds.forEach((ids) => {
      if (ids.includes(separator)) {
        let arr = ids.split(separator);
        if (arr.length == 2 && formModels[arr[0]][arr[1]]) {
          fileFolderIds.push(formModels[arr[0]][arr[1]]);
        } else if (
          arr.length == 3 &&
          formModels[arr[0]][arr[1]] &&
          Array.isArray(formModels[arr[0]][arr[1]])
        ) {
          formModels[arr[0]][arr[1]].forEach((o) => {
            fileFolderIds.push(o[arr[2]]);
          });
        }
      }
    });
    return fileFolderIds;
  }
  const onFinish = async (values: any) => {
    await submit();
    try {
      if (validateSuccess.value) {
        let formModels = await formInformation.value.getFormModels();
        let fileFolderIds: Array<string> = getUploadFileFolderIds(formModels);
        let params: PostApprovalData = {
          approvedType: approvalData.approvedType,
          approvedResult: approvalData.approvedResult, // approvalData.approvedType 审批结果 如果为 4 就需要传buttonCode
          approvedContent: approvalData.approvedContent,
          formData: formModels,
          rejectNodeActivityId: approvalData.rejectNodeActivityId,
          taskId: props.taskId,
          fileFolderIds,
          circulateConfigs: approvalData.circulateConfigs,
          stampId: values.stampId,
          stampPassword: values.password,
        };

        let res = await postApproval(params);
        // 下一节点审批人
        let taskList: Array<ApproveTask> = [];
        if (res && res.length > 0) {
          taskList = res
            .filter((ele) => {
              return ele.isMultiInstance == false && ele.isAppoint == true;
            })
            .map((ele) => {
              return {
                taskId: ele.taskId,
                taskName: ele.taskName,
                provisionalApprover: ele.provisionalApprover,
                selectIds: [],
              };
            });
          if (taskList.length > 0) {
            approveUserData.list = taskList;
            approveUserData.schemaId = props.schemaId;
            approveUserData.visible = true;
            data.submitLoading = false;
          } else {
            close();
            data.submitLoading = false;
            save(true, t('审批流程'));
          }
        } else {
          close();
          data.submitLoading = false;
          save(true, t('审批流程'));
        }
      }
    } catch (error) {}
  };

  const onFinishFailed = () => {
    submit();
  };
  async function submit() {
    data.submitLoading = true;
    validateSuccess.value = false;
    try {
      let validateForms = await formInformation.value.validateForm();
      if (validateForms.length > 0) {
        let successValidate = validateForms.filter((ele) => {
          return ele.validate;
        });
        if (successValidate.length == validateForms.length) {
          validateSuccess.value = true;
          data.submitLoading = false;
        } else {
          data.submitLoading = false;
          notificationError(t('审批流程'), t('表单校验未通过'));
        }
      }
    } catch (error) {
      data.submitLoading = false;
      notificationError(t('审批流程'), t('审批流程失败'));
    }
  }

  function changeApproveUserData() {
    approveUserData.visible = false;
    close();
  }
  function save(res: boolean, title: string) {
    if (res) {
      notificationSuccess(title);
      close();
    } else {
      notificationError(title);
    }
  }
  function close() {
    showVisible.value = false;
    emits('close');
    printData.value = {
      borderColor: '#000000',
      style: '1',
      underline: '0',
      submitLoading: false,
    };
  }
  function reset() {
    approvalData.isAddOrSubSign = false;
    approvalData.stampInfo = {
      stampId: '',
      password: '',
    };
    approvalData.buttonConfigs = [];
    approvalData.approvedType = ApproveType.AGREE;
    approvalData.approvedContent = '';
    approvalData.rejectNodeActivityId = '';
    approvalData.rejectNodeActivityIds = [];
    approvalData.circulateConfigs = [];
  }

  function printForm() {
    isShowPrint.value = true;
  }
</script>
<style lang="less" scoped>
  .description-box {
    display: flex;
    flex-direction: column;
    padding-top: 10px;
    align-items: center;
    justify-content: center;
    color: rgb(102 102 102 / 99.6%);
    margin-bottom: 20px;

    .title {
      align-self: flex-start;
      margin-bottom: 20px;
    }

    .item-box {
      align-self: flex-start;
      width: 100%;
    }

    .text-box {
      display: flex;
      margin: 10px 0;

      .text-label {
        width: 80px;
        height: 40px;
        display: inline-flex;
        justify-content: flex-end;
        margin-right: 4px;
      }
    }
  }
  // 传阅人
  :deep(.opr-box) {
    flex-direction: column !important;

    .header-box {
      flex-basis: 40px !important;
    }

    .button-box {
      flex-direction: row !important;
    }
  }

  .approve-group {
    .ant-radio-wrapper {
      margin-right: 0;
    }
  }

  :deep(span.ant-radio + *) {
    padding-right: 12px;
    padding-left: 4px;
  }

  :deep(.ant-form) {
    &.approval-form {
      .ant-form-item-label label {
        width: 90px;
        margin-left: -9px;
        margin-right: 14px;
      }

      .ant-form-item-control-input {
        margin-left: 2px;
      }
    }
  }
</style>
